package com.rbac.admin.service.auth.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.rbac.admin.common.result.ResultCode;
import com.rbac.admin.common.util.PasswordUtil;
import com.rbac.admin.dto.auth.LoginDTO;
import com.rbac.admin.dto.auth.LoginResultDTO;
import com.rbac.admin.entity.system.SystemUser;
import com.rbac.admin.entity.system.SystemRole;
import com.rbac.admin.service.auth.AuthService;
import com.rbac.admin.service.system.MenuService;
import com.rbac.admin.service.system.RoleService;
import com.rbac.admin.service.system.UserService;
import com.rbac.admin.service.system.UserDeptService;
import com.rbac.admin.vo.system.DeptVO;
import com.rbac.admin.vo.system.RoleVO;
import com.rbac.admin.vo.system.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 认证服务实现类
 *
 * @author rbac-admin
 * @since 2024-07-18
 */
@Service
public class AuthServiceImpl implements AuthService {

    // 服务注入
    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserDeptService userDeptService;

    @Override
    public LoginResultDTO login(LoginDTO loginDTO) {
        // 从数据库查询用户信息
        SystemUser user = userService.getUserByUsername(loginDTO.getUsername());
        
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_EXIST.getMessage());
        }
        
        // 检查用户状态
        if (user.getStatus() == 0) {
            throw new RuntimeException("用户已被禁用");
        }
        
        // 验证密码 (使用BCrypt加密验证)
        if (!PasswordUtil.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException(ResultCode.USERNAME_PASSWORD_ERROR.getMessage());
        }

        // 获取当前请求的IP地址
        String ip = getIpAddress();
        
        // 生成登录令牌
        StpUtil.login(user.getId());
        
        // 构建用户视图对象
        UserVO userVO = buildUserVO(user, ip);
        
        // 构建登录结果
        LoginResultDTO resultDTO = new LoginResultDTO();
        resultDTO.setToken(StpUtil.getTokenValue());
        resultDTO.setRefreshToken(StpUtil.getTokenValue()); // 实际项目中应该生成不同的刷新令牌
        resultDTO.setUserInfo(userVO);
        
        return resultDTO;
    }

    @Override
    public void logout() {
        StpUtil.logout();
    }

    @Override
    public UserVO getCurrentUserInfo() {
        // 获取当前登录用户ID
        String userId = StpUtil.getLoginIdAsString();
        
        // 从数据库查询用户信息
        SystemUser user = userService.getById(userId);
        if (user == null) {
            throw new RuntimeException(ResultCode.USER_NOT_EXIST.getMessage());
        }
        
        return buildUserVO(user, getIpAddress());
    }

    @Override
    public String refreshToken(String refreshToken) {
        // 刷新令牌逻辑
        return StpUtil.getTokenValue();
    }

    /**
     * 构建用户视图对象
     *
     * @param user 用户实体
     * @param ip 登录IP
     * @return 用户视图对象
     */
    private UserVO buildUserVO(SystemUser user, String ip) {
        UserVO userVO = new UserVO();
        userVO.setId(String.valueOf(user.getId()));
        userVO.setUsername(user.getUsername());
        userVO.setNickname(user.getNickname());
        userVO.setEmail(user.getEmail());
        userVO.setPhone(user.getPhone());
        userVO.setAvatar(user.getAvatar());
        userVO.setStatus(user.getStatus());
//        userVO.setLoginIp(ip);
//        userVO.setLoginTime(LocalDateTime.now());
        
        // 查询用户角色
        List<SystemRole> roles = roleService.getRolesByUserId(String.valueOf(user.getId()));
        List<RoleVO> roleVOs = roles.stream().map(role -> {
            RoleVO roleVO = new RoleVO();
            roleVO.setId(String.valueOf(role.getId()));
            roleVO.setRoleName(role.getRoleName());
            roleVO.setRoleCode(role.getRoleCode());
            roleVO.setStatus(role.getStatus());
            return roleVO;
        }).collect(Collectors.toList());
        userVO.setRoles(roleVOs);
        
        // 查询用户权限
        List<String> permissions = menuService.getPermissionsByUserId(String.valueOf(user.getId()));
        userVO.setPermissions(permissions);
        
        // 查询用户部门信息
        userVO.setMainDeptId(user.getMainDeptId() != null ? Integer.parseInt(user.getMainDeptId()) : null);
        userVO.setDeptName(user.getDeptName());
        
        // 获取用户的多部门信息
        List<DeptVO> depts = userDeptService.getDeptsByUserId(String.valueOf(user.getId()));
        userVO.setDepts(depts != null ? depts : new ArrayList<>());
        
        return userVO;
    }

    /**
     * 获取请求IP地址
     *
     * @return IP地址
     */
    private String getIpAddress() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        return ip;
    }
}